<template>
  <div class="map-container">
    <div ref="mapContainer" style="height: 100%; width: 100%;"></div>
    <Imageviewer 
    :images="imageUrls" 
    :show="showViewer"
    @close="showViewer = false"
  />
  </div>
</template>

<script setup>
import Imageviewer from './Imageviewer.vue'
import { onMounted, ref } from 'vue'
import L from 'leaflet'
import { openDB } from 'idb'
import 'leaflet/dist/leaflet.css'
import 'leaflet.markercluster/dist/MarkerCluster.css'
import 'leaflet.markercluster/dist/MarkerCluster.Default.css'
import 'leaflet.markercluster'

const showViewer = ref(false)
const imageUrls = ref([])
const dateRange = ref([])

/**
 * 解析EXIF日期字符串为Date对象
 * @param {string} exifDate - EXIF格式的日期字符串 (YYYY:MM:DD HH:MM:SS)
 * @returns {Date|null} 解析后的Date对象，解析失败返回null
 */
function parseExifDate(exifDate) {
  if (!exifDate) return null
  try {
    console.log(exifDate)
    // 处理时间戳格式
    if (typeof exifDate === 'number' || /^\d+$/.test(exifDate)) {
      return new Date(parseInt(exifDate) * 1000)
    }
    // 处理原始字符串格式
    const [datePart, timePart] = exifDate.split(' ')
    const [year, month, day] = datePart.split(':')
    const [hour, minute, second] = timePart.split(':')
    return new Date(year, month - 1, day, hour, minute, second)
  } catch (e) {
    console.warn('Failed to parse EXIF date:', exifDate)
    return null
  }
}

/**
 * 检查图片是否在日期范围内
 * @param {Object} image - 图片数据对象
 * @param {Array} range - 日期范围数组 [startDate, endDate]
 * @returns {boolean} 是否在范围内
 */
function isImageInDateRange(image, range) {
  if (!range || range.length !== 2 || !range[0] || !range[1]) return true
  
  const exifDate = image.exifData?.DateTimeOriginal || 
                  image.exifData?.DateTimeDigitized || 
                  image.exifData?.DateTime
  const photoDate = parseExifDate(exifDate)
  if (!photoDate) return true
  
  const [start, end] = range
  return photoDate >= start && photoDate <= end
}


// 确保输入数据转换为ArrayBuffer格式
function ensureArrayBuffer(fileData) {
  let buffer
  if (fileData instanceof ArrayBuffer) {
    buffer = fileData
  } else {
    // 统一转换为Uint8Array再获取buffer
    buffer = new Uint8Array(fileData).buffer
  }
  return buffer
}

/**
 * 将WGS-84坐标转换为GCJ-02坐标(火星坐标系)
 * @param {number} lng - 经度
 * @param {number} lat - 纬度
 * @returns {Array} 转换后的[经度, 纬度]
 */
function wgs84ToGcj02(lng, lat) {
  const a = 6378245.0
  const ee = 0.00669342162296594323
  
  if (outOfChina(lng, lat)) {
    return [lng, lat]
  }
  
  let dLat = transformLat(lng - 105.0, lat - 35.0)
  let dLng = transformLng(lng - 105.0, lat - 35.0)
  
  const radLat = lat / 180.0 * Math.PI
  let magic = Math.sin(radLat)
  magic = 1 - ee * magic * magic
  const sqrtMagic = Math.sqrt(magic)
  
  dLat = (dLat * 180.0) / ((a * (1 - ee)) / (magic * sqrtMagic) * Math.PI)
  dLng = (dLng * 180.0) / (a / sqrtMagic * Math.cos(radLat) * Math.PI)
  
  return [lng + dLng, lat + dLat]
}

function outOfChina(lng, lat) {
  return lng < 72.004 || lng > 137.8347 || lat < 0.8293 || lat > 55.8271
}

function transformLat(x, y) {
  let ret = -100.0 + 2.0 * x + 3.0 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Math.sqrt(Math.abs(x))
  ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(y * Math.PI) + 40.0 * Math.sin(y / 3.0 * Math.PI)) * 2.0 / 3.0
  ret += (160.0 * Math.sin(y / 12.0 * Math.PI) + 320 * Math.sin(y * Math.PI / 30.0)) * 2.0 / 3.0
  return ret
}

function transformLng(x, y) {
  let ret = 300.0 + x + 2.0 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Math.sqrt(Math.abs(x))
  ret += (20.0 * Math.sin(6.0 * x * Math.PI) + 20.0 * Math.sin(2.0 * x * Math.PI)) * 2.0 / 3.0
  ret += (20.0 * Math.sin(x * Math.PI) + 40.0 * Math.sin(x / 3.0 * Math.PI)) * 2.0 / 3.0
  ret += (150.0 * Math.sin(x / 12.0 * Math.PI) + 300.0 * Math.sin(x / 30.0 * Math.PI)) * 2.0 / 3.0
  return ret
}

// 初始化IndexedDB
const initDB = async () => {
  return openDB('imageMetadataDB', 1, {
    upgrade(db) {
      if (!db.objectStoreNames.contains('images')) {
        db.createObjectStore('images', { keyPath: 'fileHash' })
      }
    }
  })
}


const mapContainer = ref(null)

const map = ref(null)
const markers = ref(null)

// 从数据库加载图片数据并创建标记
/**
 * 创建地图标记
 * @param {Object} image - 图片数据对象，包含exif信息和文件信息
 * @param {ArrayBuffer} buffer - 图片二进制数据
 * @returns {L.Marker|null} 返回Leaflet标记对象，如果创建失败返回null
 */
async function createMapMarker(image, buffer) {
  try {
    if (!image.exifData?.GPSLatitude || !image.exifData?.GPSLongitude) return null;
    
    const lat = image.exifData.GPSLatitude;
    const lng = image.exifData.GPSLongitude;
    const [gcjLng, gcjLat] = wgs84ToGcj02(lng, lat);
    
    if (!L || !L.marker) {
      console.error('Leaflet is not properly loaded');
      return null;
    }
    
    const marker = L.marker([gcjLat, gcjLng], {
      title: image.fileName,
      icon: L.icon({
        iconUrl: image.thumbnailUrl,
        iconSize: [40, 40],
        iconAnchor: [20, 20],
        popupAnchor: [0, -20]
      }),
      customData: {
        imageUrl: URL.createObjectURL(new Blob([buffer], {type: 'image/jpeg'})),
        fileName: image.fileName,
        filePath: image.filePath,
      }
    });
    
    if (marker && typeof marker.on === 'function') {
      marker.on('click', function() {
        imageUrls.value = [{
          url: marker.options.customData.imageUrl,
          filePath: marker.options.customData.filePath
        }];
        // imageUrls.value = [marker.options.customData.imageUrl];
        showViewer.value = true;
      });
    }
    
    return marker;
  } catch (error) {
    console.error('Error in createMapMarker:', error);
    return null;
  }
}

/**
 * 初始化标记聚类组
 * 创建Leaflet的MarkerClusterGroup实例并配置自定义聚类图标
 */
function initMarkerClusterGroup() {
  markers.value = L.markerClusterGroup({
    iconCreateFunction: function(cluster) {
      const childMarkers = cluster.getAllChildMarkers();
      const firstMarker = childMarkers[0];
      const iconUrl = firstMarker.options.icon.options.iconUrl;
      
      return L.divIcon({
        html: `
          <div style="position:relative;width:40px;height:40px;">
            <img src="${iconUrl}" 
                 style="width:100%;height:100%;border-radius:50%;object-fit:cover;border:2px solid white;box-shadow:0 0 5px rgba(0,0,0,0.3)"/>
            <div style="position:absolute;bottom:-8px;right:-8px;background:#42b983;color:white;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;border:2px solid white;">
              ${childMarkers.length}
            </div>
          </div>
        `,
        className: 'marker-cluster-custom',
        iconSize: L.point(40, 40)
      });
    }
  });
  map.value.addLayer(markers.value);
}

/**
 * 从数据库加载已存储的图片数据并在地图上创建标记
 * 1. 从IndexedDB获取所有图片数据
 * 2. 为每张有GPS信息的图片创建地图标记
 * 3. 将标记添加到聚类组
 */
async function loadStoredImages(range) {
  try {
    const db = await initDB();
    const allImages = await db.getAll('images');
    
    if (allImages.length === 0) {
      console.log('数据库中没有存储的图片数据');
      return;
    }
    
    console.log(`从数据库加载了 ${allImages.length} 张图片数据`);
    
    if (!markers.value) initMarkerClusterGroup();
    
    // 清除现有标记
    markers.value.clearLayers();
    
    for (const image of allImages) {
      if (!isImageInDateRange(image, range)) continue;
      
      const fileData = await window.electronAPI.readFile(image.filePath, 'binary');
      const buffer = ensureArrayBuffer(fileData);
      const marker = await createMapMarker(image, buffer);
      if (marker) markers.value.addLayer(marker);
    }
    
    if (map.value) markers.value.refreshClusters();
  } catch (error) {
    console.error('加载存储的图片数据时出错:', error);
  }
}

/**
 * 将处理后的图片数据添加到地图
 * @param {Array} processedImages - 处理后的图片数据数组
 * 1. 确保标记聚类组已初始化
 * 2. 为每张图片创建标记并添加到聚类组
 * 3. 刷新聚类显示
 */
const addMarkersToMap = async (processedImages, range) => {
  try {
    if (!markers.value) initMarkerClusterGroup();
    
    // 清除现有标记
    markers.value.clearLayers();
    
    for (const image of processedImages) {
      if (!isImageInDateRange(image, range)) continue;
      
      const marker = await createMapMarker(image, image.buffer);
      if (marker) {
        if (markers.value && typeof markers.value.addLayer === 'function') {
          markers.value.addLayer(marker);
        } else {
          console.error('markers.value is not properly initialized');
          return;
        }
      }
    }
    
    if (map.value && markers.value) {
      markers.value.refreshClusters();
    }
  } catch (error) {
    console.error('Error in addMarkersToMap:', error);
    throw error;
  }
};
// 组件挂载时初始化地图
// 监听清除事件
const emit = defineEmits(['clearAllMarkers'])

onMounted(async () => {
  // 1. 创建Leaflet地图实例
  // 2. 添加高德地图底图
  // 3. 初始化标记聚类组
  // 4. 加载已存储的图片数据
  // 5. 设置聚类点击事件处理
  if (mapContainer.value) {
    map.value = L.map(mapContainer.value).setView([23.55, 116.36], 12) // 默认揭阳中心点
    markers.value = L.markerClusterGroup({
      iconCreateFunction: function(cluster) {
        const childMarkers = cluster.getAllChildMarkers()
        const firstMarker = childMarkers[0]
        
        // 使用第一个标记的图标作为基础
        const iconUrl = firstMarker.options.icon.options.iconUrl
        
        return L.divIcon({
          html: `
            <div style="position:relative;width:40px;height:40px;">
              <img src="${iconUrl}" 
                   style="width:100%;height:100%;border-radius:50%;object-fit:cover;border:2px solid white;box-shadow:0 0 5px rgba(0,0,0,0.3)"/>
              <div style="position:absolute;bottom:-8px;right:-8px;background:#42b983;color:white;border-radius:50%;width:20px;height:20px;display:flex;align-items:center;justify-content:center;font-size:10px;font-weight:bold;border:2px solid white;">
                ${childMarkers.length}
              </div>
            </div>
          `,
          className: 'marker-cluster-custom',
          iconSize: L.point(40, 40)
        })
      }
    })
    
    // 添加高德矢量底图
    //http://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}'
    //https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}
    L.tileLayer('https://webrd04.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}', {
      maxZoom: 18,
      minZoom: 3,
      attribution: '© <a href="https://ditu.amap.com/">高德地图</a>'
    }).addTo(map.value)
    
    map.value.addLayer(markers.value)
    
    // 加载已存储的图片数据
    await loadStoredImages()
    
    // 点击聚类时显示图片展示页
    markers.value.on('clusterclick', function (a) {
      const clusterMarkers = a.layer.getAllChildMarkers()
      imageUrls.value = clusterMarkers.map(marker => ({
        url: marker.options.customData.imageUrl,
        filePath: marker.options.customData.filePath
      }));
      // const urls = clusterMarkers.map(marker => marker.options.customData.imageUrl)
      // imageUrls.value=urls
      showViewer.value = true
    })
  }
})
// 处理日期范围变化
const handleDateRangeChange = (range) => {
  dateRange.value = range
  loadStoredImages(range)
}

const clearAllMarkers = () => {
  if (markers.value) {
    markers.value.clearLayers()
  }
  // 清除IndexedDB数据
  initDB().then(db => db.clear('images'))
}

defineExpose({
  addMarkersToMap,
  handleDateRangeChange,
  clearAllMarkers
})

</script>

<style>
.marker-cluster-custom {
  border: none !important;
}
</style>

<style scoped>
.map-container {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  border: none;
  border-radius: 0;
  overflow: hidden;
}
</style>